package com.alan.springbootwp.util;

import com.alan.springbootwp.model.message.*;
import com.thoughtworks.xstream.XStream;
import lombok.extern.slf4j.Slf4j;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.http.HttpServletRequest;
import java.io.InputStream;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author Alan
 * @Description
 * @date 2020年03月30日 21:53
 */
@Slf4j
public class MessageUtil {

    /**
     * 解析微信请求
     * @param request
     * @return
     * @throws Exception
     */
    public static Map<String, String> parseXml(HttpServletRequest request) throws Exception {
        // 将解析结果存储在HashMap中
        Map<String, String> map = new HashMap();
        // 从request中取得输入流
        InputStream inputStream = request.getInputStream();
        // 读取输入流
        SAXReader reader = new SAXReader();
        Document document = reader.read(inputStream);

        // 得到xml根元素
        Element root = document.getRootElement();
        // 得到根元素的所有子节点
        List<Element> elementList = root.elements();

        // 遍历所有子节点
        for (Element e : elementList) {
            map.put(e.getName(), e.getText());
        }
        // 释放资源
        inputStream.close();

        return map;
    }

    /**
     * 构造文本消息
     * @param map
     * @param content
     * @return
     */
    public static String buildTextMessage(Map<String, String> map, String content) {
        String fromUserName = map.get("FromUserName");
        String toUserName = map.get("ToUserName");

        String format = "<xml>" +
                "<ToUserName><![CDATA[%s]]></ToUserName>" +
                "<FromUserName><![CDATA[%s]]></FromUserName>" +
                "<CreateTime>%s</CreateTime>" +
                "<MsgType><![CDATA[text]]></MsgType>" +
                "<Content><![CDATA[%s]]></Content>" +
                "</xml>";

        return String.format(format, fromUserName, toUserName, String.valueOf(getUtcTime()), content);
    }

    /**
     * 构造图片消息
     * @param map
     * @param mediaId 图片ID
     * @return
     */
    public static String buildImageMessage(Map<String, String> map, String mediaId) {
        String fromUserName = map.get("FromUserName");
        String toUserName = map.get("ToUserName");
        String message = null;
        Media image = new Media();
        image.setMediaId(mediaId);
        ImageMessage imageMessage = new ImageMessage();
        imageMessage.setFromUserName(toUserName);
        imageMessage.setToUserName(fromUserName);
        imageMessage.setMsgType(WeChatConstant.MESSAGE_TYPE_IMAGE);
        imageMessage.setCreateTime(getUtcTime());
        imageMessage.setImage(image);
        message = imageMessageToXml(imageMessage);
        return message;
    }

    /**
     * 构造语音消息
     * @param map
     * @param mediaId
     * @return
     */
    public static String buildVoiceMessage(Map<String, String> map, String mediaId) {
        String fromUserName = map.get("FromUserName");
        String toUserName = map.get("ToUserName");
        String message = null;
        Media voice = new Media();
        voice.setMediaId(mediaId);
        VoiceMessage voiceMessage = new VoiceMessage();
        voiceMessage.setFromUserName(toUserName);
        voiceMessage.setToUserName(fromUserName);
        voiceMessage.setMsgType(WeChatConstant.MESSAGE_TYPE_VOICE);
        voiceMessage.setCreateTime(getUtcTime());
        voiceMessage.setVoice(voice);
        message = voiceMessageToXml(voiceMessage);
        return message;
    }

    /**
     * 构造视频消息
     * @param map
     * @param video
     * @return
     */
    public static String buildVideoMessage(Map<String, String> map, Video video) {
        String fromUserName = map.get("FromUserName");
        String toUserName = map.get("ToUserName");
        String message = null;
        VideoMessage videoMessage = new VideoMessage();
        videoMessage.setFromUserName(toUserName);
        videoMessage.setToUserName(fromUserName);
        videoMessage.setMsgType(WeChatConstant.MESSAGE_TYPE_VIDEO);
        videoMessage.setCreateTime(getUtcTime());
        videoMessage.setVideo(video);
        message = videoMessageToXml(videoMessage);
        return message;
    }

    /**
     * 构造音乐消息
     * @param map
     * @param music
     * @return
     */
    public static String buildMusicMessage(Map<String, String> map, Music music) {
        String fromUserName = map.get("FromUserName");
        String toUserName = map.get("ToUserName");
        String message = null;

        MusicMessage musicMessage = new MusicMessage();
        musicMessage.setFromUserName(toUserName);
        musicMessage.setToUserName(fromUserName);
        musicMessage.setMsgType(WeChatConstant.MESSAGE_TYPE_MUSIC);
        musicMessage.setCreateTime(getUtcTime());
        musicMessage.setMusic(music);
        message = musicMessageToXml(musicMessage);
        return message;
    }


    /**
     * 构造图文消息
     * @param map
     * @param
     * @return
     */
    public static String buildNewsMessage(Map<String, String> map, List<News> newsList) {
        String fromUserName = map.get("FromUserName");
        String toUserName = map.get("ToUserName");
        String message = null;

        NewsMessage newsMessage = new NewsMessage();
        newsMessage.setFromUserName(toUserName);
        newsMessage.setToUserName(fromUserName);
        newsMessage.setMsgType(WeChatConstant.MESSAGE_TYPE_NEWS);
        newsMessage.setCreateTime(getUtcTime());
        newsMessage.setArticleCount(newsList.size());

        newsMessage.setArticles(newsList);
        message = newsMessageToXml(newsMessage);
        return message;
    }



    /**
     * 图片消息对象转换成xml
     * @param imageMessage
     * @return
     */
    private static String imageMessageToXml(ImageMessage imageMessage){
        XStream xstream = new XStream();
        xstream.alias("xml", imageMessage.getClass());
        return xstream.toXML(imageMessage);
    }

    /**
     * @Description: 语音消息对象转换成xml
     * @param @param voiceMessage
     * @param @return
     */
    public static String voiceMessageToXml(VoiceMessage voiceMessage) {
        XStream xstream = new XStream();
        xstream.alias("xml", voiceMessage.getClass());
        return xstream.toXML(voiceMessage);
    }

    /**
     * @Description: 视频消息对象转换成xml
     * @param @param videoMessage
     * @param @return
     */
    public static String videoMessageToXml(VideoMessage videoMessage) {
        XStream xstream = new XStream();
        xstream.alias("xml", videoMessage.getClass());
        return xstream.toXML(videoMessage);
    }

    /**
     * @Description: 音乐消息对象转换成xml
     * @param @param musicMessage
     * @param @return
     */
    public static String musicMessageToXml(MusicMessage musicMessage) {
        XStream xstream = new XStream();
        xstream.alias("xml", musicMessage.getClass());
        return xstream.toXML(musicMessage);
    }

    /**
     * @Description: 图文消息对象转换成xml
     * @param @param newsMessage
     * @param @return
     */
    public static String newsMessageToXml(NewsMessage newsMessage) {
        XStream xstream = new XStream();
        xstream.alias("xml", newsMessage.getClass());
        xstream.alias("item", new News().getClass());
        return xstream.toXML(newsMessage);
    }


    
    private static long getUtcTime() {
        Date date = new Date();
        DateFormat dateFormatter = new SimpleDateFormat("yyyyMMddHHmm");
        String curDate = dateFormatter.format(date);
        long dd = Long.valueOf(0);

        try {
            dd = dateFormatter.parse(curDate).getTime();
        } catch (ParseException e) {
            e.printStackTrace();
        }

        return dd;
    }
}
